Autogenerated HTML docs for v2.17.0-582-gccdcb 
diff --git a/technical/api-submodule-config.html b/technical/api-submodule-config.html index 4a94fc0..74f1567 100644 --- a/technical/api-submodule-config.html +++ b/technical/api-submodule-config.html 
@@ -1,9 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?>   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">   <head>   <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />  -<meta name="generator" content="AsciiDoc 8.6.9" />  +<meta name="generator" content="AsciiDoc 8.6.10" />   <title>submodule config cache API</title>   <style type="text/css">   /* Shared CSS for AsciiDoc xhtml11 and html5 backends */  @@ -785,7 +786,7 @@  <div class="sectionbody">   <div class="dlist"><dl>   <dt class="hdlist1">  -<code>void submodule_free()</code>  +<code>void submodule_free(struct repository *r)</code>   </dt>   <dd>   <p>  @@ -833,7 +834,7 @@  <div id="footer">   <div id="footer-text">   Last updated  - 2018-02-28 15:39:58 PST  + 2018-05-08 16:51:20 JST   </div>   </div>   </body>  
diff --git a/technical/api-submodule-config.txt b/technical/api-submodule-config.txt index ee907c4..fb06089 100644 --- a/technical/api-submodule-config.txt +++ b/technical/api-submodule-config.txt 
@@ -38,7 +38,7 @@  Functions  ---------   -`void submodule_free()`:: +`void submodule_free(struct repository *r)`::   	Use these to free the internally cached values.   
diff --git a/technical/commit-graph-format.txt b/technical/commit-graph-format.txt new file mode 100644 index 0000000..ad6af81 --- /dev/null +++ b/technical/commit-graph-format.txt 
@@ -0,0 +1,97 @@ +Git commit graph format +======================= + +The Git commit graph stores a list of commit OIDs and some associated +metadata, including: + +- The generation number of the commit. Commits with no parents have + generation number 1; commits with parents have generation number + one more than the maximum generation number of its parents. We + reserve zero as special, and can be used to mark a generation + number invalid or as "not computed". + +- The root tree OID. + +- The commit date. + +- The parents of the commit, stored using positional references within + the graph file. + +These positional references are stored as unsigned 32-bit integers +corresponding to the array position withing the list of commit OIDs. We +use the most-significant bit for special purposes, so we can store at most +(1 << 31) - 1 (around 2 billion) commits. + +== Commit graph files have the following format: + +In order to allow extensions that add extra data to the graph, we organize +the body into "chunks" and provide a binary lookup table at the beginning +of the body. The header includes certain values, such as number of chunks +and hash type. + +All 4-byte numbers are in network order. + +HEADER: + + 4-byte signature: + The signature is: {'C', 'G', 'P', 'H'} + + 1-byte version number: + Currently, the only valid version is 1. + + 1-byte Hash Version (1 = SHA-1) + We infer the hash length (H) from this value. + + 1-byte number (C) of "chunks" + + 1-byte (reserved for later use) + Current clients should ignore this value. + +CHUNK LOOKUP: + + (C + 1) * 12 bytes listing the table of contents for the chunks: + First 4 bytes describe the chunk id. Value 0 is a terminating label. + Other 8 bytes provide the byte-offset in current file for chunk to + start. (Chunks are ordered contiguously in the file, so you can infer + the length using the next chunk position if necessary.) Each chunk + ID appears at most once. + + The remaining data in the body is described one chunk at a time, and + these chunks may be given in any order. Chunks are required unless + otherwise specified. + +CHUNK DATA: + + OID Fanout (ID: {'O', 'I', 'D', 'F'}) (256 * 4 bytes) + The ith entry, F[i], stores the number of OIDs with first + byte at most i. Thus F[255] stores the total + number of commits (N). + + OID Lookup (ID: {'O', 'I', 'D', 'L'}) (N * H bytes) + The OIDs for all commits in the graph, sorted in ascending order. + + Commit Data (ID: {'C', 'G', 'E', 'T' }) (N * (H + 16) bytes) + * The first H bytes are for the OID of the root tree. + * The next 8 bytes are for the positions of the first two parents + of the ith commit. Stores value 0xffffffff if no parent in that + position. If there are more than two parents, the second value + has its most-significant bit on and the other bits store an array + position into the Large Edge List chunk. + * The next 8 bytes store the generation number of the commit and + the commit time in seconds since EPOCH. The generation number + uses the higher 30 bits of the first 4 bytes, while the commit + time uses the 32 bits of the second 4 bytes, along with the lowest + 2 bits of the lowest byte, storing the 33rd and 34th bit of the + commit time. + + Large Edge List (ID: {'E', 'D', 'G', 'E'}) [Optional] + This list of 4-byte values store the second through nth parents for + all octopus merges. The second parent value in the commit data stores + an array position within this list along with the most-significant bit + on. Starting at that array position, iterate through this list of commit + positions for the parents until reaching a value with the most-significant + bit on. The other bits correspond to the position of the last parent. + +TRAILER: + +	H-byte HASH-checksum of all of the above. 
diff --git a/technical/commit-graph.txt b/technical/commit-graph.txt new file mode 100644 index 0000000..0550c6d --- /dev/null +++ b/technical/commit-graph.txt 
@@ -0,0 +1,163 @@ +Git Commit Graph Design Notes +============================= + +Git walks the commit graph for many reasons, including: + +1. Listing and filtering commit history. +2. Computing merge bases. + +These operations can become slow as the commit count grows. The merge +base calculation shows up in many user-facing commands, such as 'merge-base' +or 'status' and can take minutes to compute depending on history shape. + +There are two main costs here: + +1. Decompressing and parsing commits. +2. Walking the entire graph to satisfy topological order constraints. + +The commit graph file is a supplemental data structure that accelerates +commit graph walks. If a user downgrades or disables the 'core.commitGraph' +config setting, then the existing ODB is sufficient. The file is stored +as "commit-graph" either in the .git/objects/info directory or in the info +directory of an alternate. + +The commit graph file stores the commit graph structure along with some +extra metadata to speed up graph walks. By listing commit OIDs in lexi- +cographic order, we can identify an integer position for each commit and +refer to the parents of a commit using those integer positions. We use +binary search to find initial commits and then use the integer positions +for fast lookups during the walk. + +A consumer may load the following info for a commit from the graph: + +1. The commit OID. +2. The list of parents, along with their integer position. +3. The commit date. +4. The root tree OID. +5. The generation number (see definition below). + +Values 1-4 satisfy the requirements of parse_commit_gently(). + +Define the "generation number" of a commit recursively as follows: + + * A commit with no parents (a root commit) has generation number one. + + * A commit with at least one parent has generation number one more than + the largest generation number among its parents. + +Equivalently, the generation number of a commit A is one more than the +length of a longest path from A to a root commit. The recursive definition +is easier to use for computation and observing the following property: + + If A and B are commits with generation numbers N and M, respectively, + and N <= M, then A cannot reach B. That is, we know without searching + that B is not an ancestor of A because it is further from a root commit + than A. + + Conversely, when checking if A is an ancestor of B, then we only need + to walk commits until all commits on the walk boundary have generation + number at most N. If we walk commits using a priority queue seeded by + generation numbers, then we always expand the boundary commit with highest + generation number and can easily detect the stopping condition. + +This property can be used to significantly reduce the time it takes to +walk commits and determine topological relationships. Without generation +numbers, the general heuristic is the following: + + If A and B are commits with commit time X and Y, respectively, and + X < Y, then A _probably_ cannot reach B. + +This heuristic is currently used whenever the computation is allowed to +violate topological relationships due to clock skew (such as "git log" +with default order), but is not used when the topological order is +required (such as merge base calculations, "git log --graph"). + +In practice, we expect some commits to be created recently and not stored +in the commit graph. We can treat these commits as having "infinite" +generation number and walk until reaching commits with known generation +number. + +Design Details +-------------- + +- The commit graph file is stored in a file named 'commit-graph' in the + .git/objects/info directory. This could be stored in the info directory + of an alternate. + +- The core.commitGraph config setting must be on to consume graph files. + +- The file format includes parameters for the object ID hash function, + so a future change of hash algorithm does not require a change in format. + +Future Work +----------- + +- The commit graph feature currently does not honor commit grafts. This can + be remedied by duplicating or refactoring the current graft logic. + +- The 'commit-graph' subcommand does not have a "verify" mode that is + necessary for integration with fsck. + +- The file format includes room for precomputed generation numbers. These + are not currently computed, so all generation numbers will be marked as + 0 (or "uncomputed"). A later patch will include this calculation. + +- After computing and storing generation numbers, we must make graph + walks aware of generation numbers to gain the performance benefits they + enable. This will mostly be accomplished by swapping a commit-date-ordered + priority queue with one ordered by generation number. The following + operations are important candidates: + + - paint_down_to_common() + - 'log --topo-order' + +- Currently, parse_commit_gently() requires filling in the root tree + object for a commit. This passes through lookup_tree() and consequently + lookup_object(). Also, it calls lookup_commit() when loading the parents. + These method calls check the ODB for object existence, even if the + consumer does not need the content. For example, we do not need the + tree contents when computing merge bases. Now that commit parsing is + removed from the computation time, these lookup operations are the + slowest operations keeping graph walks from being fast. Consider + loading these objects without verifying their existence in the ODB and + only loading them fully when consumers need them. Consider a method + such as "ensure_tree_loaded(commit)" that fully loads a tree before + using commit->tree. + +- The current design uses the 'commit-graph' subcommand to generate the graph. + When this feature stabilizes enough to recommend to most users, we should + add automatic graph writes to common operations that create many commits. + For example, one could compute a graph on 'clone', 'fetch', or 'repack' + commands. + +- A server could provide a commit graph file as part of the network protocol + to avoid extra calculations by clients. This feature is only of benefit if + the user is willing to trust the file, because verifying the file is correct + is as hard as computing it from scratch. + +Related Links +------------- +[0] https://bugs.chromium.org/p/git/issues/detail?id=8 + Chromium work item for: Serialized Commit Graph + +[1] https://public-inbox.org/git/20110713070517.GC18566@sigill.intra.peff.net/ + An abandoned patch that introduced generation numbers. + +[2] https://public-inbox.org/git/20170908033403.q7e6dj7benasrjes@sigill.intra.peff.net/ + Discussion about generation numbers on commits and how they interact + with fsck. + +[3] https://public-inbox.org/git/20170908034739.4op3w4f2ma5s65ku@sigill.intra.peff.net/ + More discussion about generation numbers and not storing them inside + commit objects. A valuable quote: + + "I think we should be moving more in the direction of keeping + repo-local caches for optimizations. Reachability bitmaps have been + a big performance win. I think we should be doing the same with our + properties of commits. Not just generation numbers, but making it + cheap to access the graph structure without zlib-inflating whole + commit objects (i.e., packv4 or something like the "metapacks" I + proposed a few years ago)." + +[4] https://public-inbox.org/git/20180108154822.54829-1-git@jeffhostetler.com/T/#u + A patch to remove the ahead-behind calculation from 'status'. 
diff --git a/technical/protocol-v2.html b/technical/protocol-v2.html new file mode 100644 index 0000000..3c68f7d --- /dev/null +++ b/technical/protocol-v2.html 
@@ -0,0 +1,1271 @@ +<?xml version="1.0" encoding="UTF-8"?>  +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"  + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">  +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">  +<head>  +<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />  +<meta name="generator" content="AsciiDoc 8.6.10" />  +<title> Git Wire Protocol, Version 2</title>  +<style type="text/css">  +/* Shared CSS for AsciiDoc xhtml11 and html5 backends */  +  +/* Default font. */  +body {  + font-family: Georgia,serif;  +}  +  +/* Title font. */  +h1, h2, h3, h4, h5, h6,  +div.title, caption.title,  +thead, p.table.header,  +#toctitle,  +#author, #revnumber, #revdate, #revremark,  +#footer {  + font-family: Arial,Helvetica,sans-serif;  +}  +  +body {  + margin: 1em 5% 1em 5%;  +}  +  +a {  + color: blue;  + text-decoration: underline;  +}  +a:visited {  + color: fuchsia;  +}  +  +em {  + font-style: italic;  + color: navy;  +}  +  +strong {  + font-weight: bold;  + color: #083194;  +}  +  +h1, h2, h3, h4, h5, h6 {  + color: #527bbd;  + margin-top: 1.2em;  + margin-bottom: 0.5em;  + line-height: 1.3;  +}  +  +h1, h2, h3 {  + border-bottom: 2px solid silver;  +}  +h2 {  + padding-top: 0.5em;  +}  +h3 {  + float: left;  +}  +h3 + * {  + clear: left;  +}  +h5 {  + font-size: 1.0em;  +}  +  +div.sectionbody {  + margin-left: 0;  +}  +  +hr {  + border: 1px solid silver;  +}  +  +p {  + margin-top: 0.5em;  + margin-bottom: 0.5em;  +}  +  +ul, ol, li > p {  + margin-top: 0;  +}  +ul > li { color: #aaa; }  +ul > li > * { color: black; }  +  +.monospaced, code, pre {  + font-family: "Courier New", Courier, monospace;  + font-size: inherit;  + color: navy;  + padding: 0;  + margin: 0;  +}  +pre {  + white-space: pre-wrap;  +}  +  +#author {  + color: #527bbd;  + font-weight: bold;  + font-size: 1.1em;  +}  +#email {  +}  +#revnumber, #revdate, #revremark {  +}  +  +#footer {  + font-size: small;  + border-top: 2px solid silver;  + padding-top: 0.5em;  + margin-top: 4.0em;  +}  +#footer-text {  + float: left;  + padding-bottom: 0.5em;  +}  +#footer-badges {  + float: right;  + padding-bottom: 0.5em;  +}  +  +#preamble {  + margin-top: 1.5em;  + margin-bottom: 1.5em;  +}  +div.imageblock, div.exampleblock, div.verseblock,  +div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,  +div.admonitionblock {  + margin-top: 1.0em;  + margin-bottom: 1.5em;  +}  +div.admonitionblock {  + margin-top: 2.0em;  + margin-bottom: 2.0em;  + margin-right: 10%;  + color: #606060;  +}  +  +div.content { /* Block element content. */  + padding: 0;  +}  +  +/* Block element titles. */  +div.title, caption.title {  + color: #527bbd;  + font-weight: bold;  + text-align: left;  + margin-top: 1.0em;  + margin-bottom: 0.5em;  +}  +div.title + * {  + margin-top: 0;  +}  +  +td div.title:first-child {  + margin-top: 0.0em;  +}  +div.content div.title:first-child {  + margin-top: 0.0em;  +}  +div.content + div.title {  + margin-top: 0.0em;  +}  +  +div.sidebarblock > div.content {  + background: #ffffee;  + border: 1px solid #dddddd;  + border-left: 4px solid #f0f0f0;  + padding: 0.5em;  +}  +  +div.listingblock > div.content {  + border: 1px solid #dddddd;  + border-left: 5px solid #f0f0f0;  + background: #f8f8f8;  + padding: 0.5em;  +}  +  +div.quoteblock, div.verseblock {  + padding-left: 1.0em;  + margin-left: 1.0em;  + margin-right: 10%;  + border-left: 5px solid #f0f0f0;  + color: #888;  +}  +  +div.quoteblock > div.attribution {  + padding-top: 0.5em;  + text-align: right;  +}  +  +div.verseblock > pre.content {  + font-family: inherit;  + font-size: inherit;  +}  +div.verseblock > div.attribution {  + padding-top: 0.75em;  + text-align: left;  +}  +/* DEPRECATED: Pre version 8.2.7 verse style literal block. */  +div.verseblock + div.attribution {  + text-align: left;  +}  +  +div.admonitionblock .icon {  + vertical-align: top;  + font-size: 1.1em;  + font-weight: bold;  + text-decoration: underline;  + color: #527bbd;  + padding-right: 0.5em;  +}  +div.admonitionblock td.content {  + padding-left: 0.5em;  + border-left: 3px solid #dddddd;  +}  +  +div.exampleblock > div.content {  + border-left: 3px solid #dddddd;  + padding-left: 0.5em;  +}  +  +div.imageblock div.content { padding-left: 0; }  +span.image img { border-style: none; vertical-align: text-bottom; }  +a.image:visited { color: white; }  +  +dl {  + margin-top: 0.8em;  + margin-bottom: 0.8em;  +}  +dt {  + margin-top: 0.5em;  + margin-bottom: 0;  + font-style: normal;  + color: navy;  +}  +dd > *:first-child {  + margin-top: 0.1em;  +}  +  +ul, ol {  + list-style-position: outside;  +}  +ol.arabic {  + list-style-type: decimal;  +}  +ol.loweralpha {  + list-style-type: lower-alpha;  +}  +ol.upperalpha {  + list-style-type: upper-alpha;  +}  +ol.lowerroman {  + list-style-type: lower-roman;  +}  +ol.upperroman {  + list-style-type: upper-roman;  +}  +  +div.compact ul, div.compact ol,  +div.compact p, div.compact p,  +div.compact div, div.compact div {  + margin-top: 0.1em;  + margin-bottom: 0.1em;  +}  +  +tfoot {  + font-weight: bold;  +}  +td > div.verse {  + white-space: pre;  +}  +  +div.hdlist {  + margin-top: 0.8em;  + margin-bottom: 0.8em;  +}  +div.hdlist tr {  + padding-bottom: 15px;  +}  +dt.hdlist1.strong, td.hdlist1.strong {  + font-weight: bold;  +}  +td.hdlist1 {  + vertical-align: top;  + font-style: normal;  + padding-right: 0.8em;  + color: navy;  +}  +td.hdlist2 {  + vertical-align: top;  +}  +div.hdlist.compact tr {  + margin: 0;  + padding-bottom: 0;  +}  +  +.comment {  + background: yellow;  +}  +  +.footnote, .footnoteref {  + font-size: 0.8em;  +}  +  +span.footnote, span.footnoteref {  + vertical-align: super;  +}  +  +#footnotes {  + margin: 20px 0 20px 0;  + padding: 7px 0 0 0;  +}  +  +#footnotes div.footnote {  + margin: 0 0 5px 0;  +}  +  +#footnotes hr {  + border: none;  + border-top: 1px solid silver;  + height: 1px;  + text-align: left;  + margin-left: 0;  + width: 20%;  + min-width: 100px;  +}  +  +div.colist td {  + padding-right: 0.5em;  + padding-bottom: 0.3em;  + vertical-align: top;  +}  +div.colist td img {  + margin-top: 0.3em;  +}  +  +@media print {  + #footer-badges { display: none; }  +}  +  +#toc {  + margin-bottom: 2.5em;  +}  +  +#toctitle {  + color: #527bbd;  + font-size: 1.1em;  + font-weight: bold;  + margin-top: 1.0em;  + margin-bottom: 0.1em;  +}  +  +div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {  + margin-top: 0;  + margin-bottom: 0;  +}  +div.toclevel2 {  + margin-left: 2em;  + font-size: 0.9em;  +}  +div.toclevel3 {  + margin-left: 4em;  + font-size: 0.9em;  +}  +div.toclevel4 {  + margin-left: 6em;  + font-size: 0.9em;  +}  +  +span.aqua { color: aqua; }  +span.black { color: black; }  +span.blue { color: blue; }  +span.fuchsia { color: fuchsia; }  +span.gray { color: gray; }  +span.green { color: green; }  +span.lime { color: lime; }  +span.maroon { color: maroon; }  +span.navy { color: navy; }  +span.olive { color: olive; }  +span.purple { color: purple; }  +span.red { color: red; }  +span.silver { color: silver; }  +span.teal { color: teal; }  +span.white { color: white; }  +span.yellow { color: yellow; }  +  +span.aqua-background { background: aqua; }  +span.black-background { background: black; }  +span.blue-background { background: blue; }  +span.fuchsia-background { background: fuchsia; }  +span.gray-background { background: gray; }  +span.green-background { background: green; }  +span.lime-background { background: lime; }  +span.maroon-background { background: maroon; }  +span.navy-background { background: navy; }  +span.olive-background { background: olive; }  +span.purple-background { background: purple; }  +span.red-background { background: red; }  +span.silver-background { background: silver; }  +span.teal-background { background: teal; }  +span.white-background { background: white; }  +span.yellow-background { background: yellow; }  +  +span.big { font-size: 2em; }  +span.small { font-size: 0.6em; }  +  +span.underline { text-decoration: underline; }  +span.overline { text-decoration: overline; }  +span.line-through { text-decoration: line-through; }  +  +div.unbreakable { page-break-inside: avoid; }  +  +  +/*  + * xhtml11 specific  + *  + * */  +  +div.tableblock {  + margin-top: 1.0em;  + margin-bottom: 1.5em;  +}  +div.tableblock > table {  + border: 3px solid #527bbd;  +}  +thead, p.table.header {  + font-weight: bold;  + color: #527bbd;  +}  +p.table {  + margin-top: 0;  +}  +/* Because the table frame attribute is overriden by CSS in most browsers. */  +div.tableblock > table[frame="void"] {  + border-style: none;  +}  +div.tableblock > table[frame="hsides"] {  + border-left-style: none;  + border-right-style: none;  +}  +div.tableblock > table[frame="vsides"] {  + border-top-style: none;  + border-bottom-style: none;  +}  +  +  +/*  + * html5 specific  + *  + * */  +  +table.tableblock {  + margin-top: 1.0em;  + margin-bottom: 1.5em;  +}  +thead, p.tableblock.header {  + font-weight: bold;  + color: #527bbd;  +}  +p.tableblock {  + margin-top: 0;  +}  +table.tableblock {  + border-width: 3px;  + border-spacing: 0px;  + border-style: solid;  + border-color: #527bbd;  + border-collapse: collapse;  +}  +th.tableblock, td.tableblock {  + border-width: 1px;  + padding: 4px;  + border-style: solid;  + border-color: #527bbd;  +}  +  +table.tableblock.frame-topbot {  + border-left-style: hidden;  + border-right-style: hidden;  +}  +table.tableblock.frame-sides {  + border-top-style: hidden;  + border-bottom-style: hidden;  +}  +table.tableblock.frame-none {  + border-style: hidden;  +}  +  +th.tableblock.halign-left, td.tableblock.halign-left {  + text-align: left;  +}  +th.tableblock.halign-center, td.tableblock.halign-center {  + text-align: center;  +}  +th.tableblock.halign-right, td.tableblock.halign-right {  + text-align: right;  +}  +  +th.tableblock.valign-top, td.tableblock.valign-top {  + vertical-align: top;  +}  +th.tableblock.valign-middle, td.tableblock.valign-middle {  + vertical-align: middle;  +}  +th.tableblock.valign-bottom, td.tableblock.valign-bottom {  + vertical-align: bottom;  +}  +  +  +/*  + * manpage specific  + *  + * */  +  +body.manpage h1 {  + padding-top: 0.5em;  + padding-bottom: 0.5em;  + border-top: 2px solid silver;  + border-bottom: 2px solid silver;  +}  +body.manpage h2 {  + border-style: none;  +}  +body.manpage div.sectionbody {  + margin-left: 3em;  +}  +  +@media print {  + body.manpage div#toc { display: none; }  +}  +  +  +</style>  +<script type="text/javascript">  +/*<![CDATA[*/  +var asciidoc = { // Namespace.  +  +/////////////////////////////////////////////////////////////////////  +// Table Of Contents generator  +/////////////////////////////////////////////////////////////////////  +  +/* Author: Mihai Bazon, September 2002  + * http://students.infoiasi.ro/~mishoo  + *  + * Table Of Content generator  + * Version: 0.4  + *  + * Feel free to use this script under the terms of the GNU General Public  + * License, as long as you do not remove or alter this notice.  + */  +  + /* modified by Troy D. Hanson, September 2006. License: GPL */  + /* modified by Stuart Rackham, 2006, 2009. License: GPL */  +  +// toclevels = 1..4.  +toc: function (toclevels) {  +  + function getText(el) {  + var text = "";  + for (var i = el.firstChild; i != null; i = i.nextSibling) {  + if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.  + text += i.data;  + else if (i.firstChild != null)  + text += getText(i);  + }  + return text;  + }  +  + function TocEntry(el, text, toclevel) {  + this.element = el;  + this.text = text;  + this.toclevel = toclevel;  + }  +  + function tocEntries(el, toclevels) {  + var result = new Array;  + var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');  + // Function that scans the DOM tree for header elements (the DOM2  + // nodeIterator API would be a better technique but not supported by all  + // browsers).  + var iterate = function (el) {  + for (var i = el.firstChild; i != null; i = i.nextSibling) {  + if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {  + var mo = re.exec(i.tagName);  + if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {  + result[result.length] = new TocEntry(i, getText(i), mo[1]-1);  + }  + iterate(i);  + }  + }  + }  + iterate(el);  + return result;  + }  +  + var toc = document.getElementById("toc");  + if (!toc) {  + return;  + }  +  + // Delete existing TOC entries in case we're reloading the TOC.  + var tocEntriesToRemove = [];  + var i;  + for (i = 0; i < toc.childNodes.length; i++) {  + var entry = toc.childNodes[i];  + if (entry.nodeName.toLowerCase() == 'div'  + && entry.getAttribute("class")  + && entry.getAttribute("class").match(/^toclevel/))  + tocEntriesToRemove.push(entry);  + }  + for (i = 0; i < tocEntriesToRemove.length; i++) {  + toc.removeChild(tocEntriesToRemove[i]);  + }  +  + // Rebuild TOC entries.  + var entries = tocEntries(document.getElementById("content"), toclevels);  + for (var i = 0; i < entries.length; ++i) {  + var entry = entries[i];  + if (entry.element.id == "")  + entry.element.id = "_toc_" + i;  + var a = document.createElement("a");  + a.href = "#" + entry.element.id;  + a.appendChild(document.createTextNode(entry.text));  + var div = document.createElement("div");  + div.appendChild(a);  + div.className = "toclevel" + entry.toclevel;  + toc.appendChild(div);  + }  + if (entries.length == 0)  + toc.parentNode.removeChild(toc);  +},  +  +  +/////////////////////////////////////////////////////////////////////  +// Footnotes generator  +/////////////////////////////////////////////////////////////////////  +  +/* Based on footnote generation code from:  + * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html  + */  +  +footnotes: function () {  + // Delete existing footnote entries in case we're reloading the footnodes.  + var i;  + var noteholder = document.getElementById("footnotes");  + if (!noteholder) {  + return;  + }  + var entriesToRemove = [];  + for (i = 0; i < noteholder.childNodes.length; i++) {  + var entry = noteholder.childNodes[i];  + if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")  + entriesToRemove.push(entry);  + }  + for (i = 0; i < entriesToRemove.length; i++) {  + noteholder.removeChild(entriesToRemove[i]);  + }  +  + // Rebuild footnote entries.  + var cont = document.getElementById("content");  + var spans = cont.getElementsByTagName("span");  + var refs = {};  + var n = 0;  + for (i=0; i<spans.length; i++) {  + if (spans[i].className == "footnote") {  + n++;  + var note = spans[i].getAttribute("data-note");  + if (!note) {  + // Use [\s\S] in place of . so multi-line matches work.  + // Because JavaScript has no s (dotall) regex flag.  + note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];  + spans[i].innerHTML =  + "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +  + "' title='View footnote' class='footnote'>" + n + "</a>]";  + spans[i].setAttribute("data-note", note);  + }  + noteholder.innerHTML +=  + "<div class='footnote' id='_footnote_" + n + "'>" +  + "<a href='#_footnoteref_" + n + "' title='Return to text'>" +  + n + "</a>. " + note + "</div>";  + var id =spans[i].getAttribute("id");  + if (id != null) refs["#"+id] = n;  + }  + }  + if (n == 0)  + noteholder.parentNode.removeChild(noteholder);  + else {  + // Process footnoterefs.  + for (i=0; i<spans.length; i++) {  + if (spans[i].className == "footnoteref") {  + var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");  + href = href.match(/#.*/)[0]; // Because IE return full URL.  + n = refs[href];  + spans[i].innerHTML =  + "[<a href='#_footnote_" + n +  + "' title='View footnote' class='footnote'>" + n + "</a>]";  + }  + }  + }  +},  +  +install: function(toclevels) {  + var timerId;  +  + function reinstall() {  + asciidoc.footnotes();  + if (toclevels) {  + asciidoc.toc(toclevels);  + }  + }  +  + function reinstallAndRemoveTimer() {  + clearInterval(timerId);  + reinstall();  + }  +  + timerId = setInterval(reinstall, 500);  + if (document.addEventListener)  + document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);  + else  + window.onload = reinstallAndRemoveTimer;  +}  +  +}  +asciidoc.install();  +/*]]>*/  +</script>  +</head>  +<body class="article">  +<div id="header">  +<h1> Git Wire Protocol, Version 2</h1>  +</div>  +<div id="content">  +<div id="preamble">  +<div class="sectionbody">  +<div class="paragraph"><p>This document presents a specification for a version 2 of Git&#8217;s wire  +protocol. Protocol v2 will improve upon v1 in the following ways:</p></div>  +<div class="ulist"><ul>  +<li>  +<p>  +Instead of multiple service names, multiple commands will be  + supported by a single service  +</p>  +</li>  +<li>  +<p>  +Easily extendable as capabilities are moved into their own section  + of the protocol, no longer being hidden behind a NUL byte and  + limited by the size of a pkt-line  +</p>  +</li>  +<li>  +<p>  +Separate out other information hidden behind NUL bytes (e.g. agent  + string as a capability and symrefs can be requested using <em>ls-refs</em>)  +</p>  +</li>  +<li>  +<p>  +Reference advertisement will be omitted unless explicitly requested  +</p>  +</li>  +<li>  +<p>  +ls-refs command to explicitly request some refs  +</p>  +</li>  +<li>  +<p>  +Designed with http and stateless-rpc in mind. With clear flush  + semantics the http remote helper can simply act as a proxy  +</p>  +</li>  +</ul></div>  +<div class="paragraph"><p>In protocol v2 communication is command oriented. When first contacting a  +server a list of capabilities will advertised. Some of these capabilities  +will be commands which a client can request be executed. Once a command  +has completed, a client can reuse the connection and request that other  +commands be executed.</p></div>  +</div>  +</div>  +<div class="sect1">  +<h2 id="_packet_line_framing"> Packet-Line Framing</h2>  +<div class="sectionbody">  +<div class="paragraph"><p>All communication is done using packet-line framing, just as in v1. See  +<code>Documentation/technical/pack-protocol.txt</code> and  +<code>Documentation/technical/protocol-common.txt</code> for more information.</p></div>  +<div class="paragraph"><p>In protocol v2 these special packets will have the following semantics:</p></div>  +<div class="ulist"><ul>  +<li>  +<p>  +<em>0000</em> Flush Packet (flush-pkt) - indicates the end of a message  +</p>  +</li>  +<li>  +<p>  +<em>0001</em> Delimiter Packet (delim-pkt) - separates sections of a message  +</p>  +</li>  +</ul></div>  +</div>  +</div>  +<div class="sect1">  +<h2 id="_initial_client_request"> Initial Client Request</h2>  +<div class="sectionbody">  +<div class="paragraph"><p>In general a client can request to speak protocol v2 by sending  +<code>version=2</code> through the respective side-channel for the transport being  +used which inevitably sets <code>GIT_PROTOCOL</code>. More information can be  +found in <code>pack-protocol.txt</code> and <code>http-protocol.txt</code>. In all cases the  +response from the server is the capability advertisement.</p></div>  +<div class="sect2">  +<h3 id="_git_transport"> Git Transport</h3>  +<div class="paragraph"><p>When using the git:// transport, you can request to use protocol v2 by  +sending "version=2" as an extra parameter:</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0</code></pre>  +</div></div>  +</div>  +<div class="sect2">  +<h3 id="_ssh_and_file_transport"> SSH and File Transport</h3>  +<div class="paragraph"><p>When using either the ssh:// or file:// transport, the GIT_PROTOCOL  +environment variable must be set explicitly to include "version=2".</p></div>  +</div>  +<div class="sect2">  +<h3 id="_http_transport"> HTTP Transport</h3>  +<div class="paragraph"><p>When using the http:// or https:// transport a client makes a "smart"  +info/refs request as described in <code>http-protocol.txt</code> and requests that  +v2 be used by supplying "version=2" in the <code>Git-Protocol</code> header.</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>C: Git-Protocol: version=2  +C:  +C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0</code></pre>  +</div></div>  +<div class="paragraph"><p>A v2 server would reply:</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>S: 200 OK  +S: &lt;Some headers&gt;  +S: ...  +S:  +S: 000eversion 2\n  +S: &lt;capability-advertisement&gt;</code></pre>  +</div></div>  +<div class="paragraph"><p>Subsequent requests are then made directly to the service  +<code>$GIT_URL/git-upload-pack</code>. (This works the same for git-receive-pack).</p></div>  +</div>  +</div>  +</div>  +<div class="sect1">  +<h2 id="_capability_advertisement"> Capability Advertisement</h2>  +<div class="sectionbody">  +<div class="paragraph"><p>A server which decides to communicate (based on a request from a client)  +using protocol version 2, notifies the client by sending a version string  +in its initial response followed by an advertisement of its capabilities.  +Each capability is a key with an optional value. Clients must ignore all  +unknown keys. Semantics of unknown values are left to the definition of  +each key. Some capabilities will describe commands which can be requested  +to be executed by the client.</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>capability-advertisement = protocol-version  + capability-list  + flush-pkt</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>protocol-version = PKT-LINE("version 2" LF)  +capability-list = *capability  +capability = PKT-LINE(key[=value] LF)</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>key = 1*(ALPHA | DIGIT | "-_")  +value = 1*(ALPHA | DIGIT | " -_.,?\/{}[]()&lt;&gt;!@#$%^&amp;*+=:;")</code></pre>  +</div></div>  +</div>  +</div>  +<div class="sect1">  +<h2 id="_command_request"> Command Request</h2>  +<div class="sectionbody">  +<div class="paragraph"><p>After receiving the capability advertisement, a client can then issue a  +request to select the command it wants with any particular capabilities  +or arguments. There is then an optional section where the client can  +provide any command specific parameters or queries. Only a single  +command can be requested at a time.</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>request = empty-request | command-request  +empty-request = flush-pkt  +command-request = command  + capability-list  + [command-args]  + flush-pkt  +command = PKT-LINE("command=" key LF)  +command-args = delim-pkt  + *command-specific-arg</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>command-specific-args are packet line framed arguments defined by  +each individual command.</code></pre>  +</div></div>  +<div class="paragraph"><p>The server will then check to ensure that the client&#8217;s request is  +comprised of a valid command as well as valid capabilities which were  +advertised. If the request is valid the server will then execute the  +command. A server MUST wait till it has received the client&#8217;s entire  +request before issuing a response. The format of the response is  +determined by the command being executed, but in all cases a flush-pkt  +indicates the end of the response.</p></div>  +<div class="paragraph"><p>When a command has finished, and the client has received the entire  +response from the server, a client can either request that another  +command be executed or can terminate the connection. A client may  +optionally send an empty request consisting of just a flush-pkt to  +indicate that no more requests will be made.</p></div>  +</div>  +</div>  +<div class="sect1">  +<h2 id="_capabilities"> Capabilities</h2>  +<div class="sectionbody">  +<div class="paragraph"><p>There are two different types of capabilities: normal capabilities,  +which can be used to to convey information or alter the behavior of a  +request, and commands, which are the core actions that a client wants to  +perform (fetch, push, etc).</p></div>  +<div class="paragraph"><p>Protocol version 2 is stateless by default. This means that all commands  +must only last a single round and be stateless from the perspective of the  +server side, unless the client has requested a capability indicating that  +state should be maintained by the server. Clients MUST NOT require state  +management on the server side in order to function correctly. This  +permits simple round-robin load-balancing on the server side, without  +needing to worry about state management.</p></div>  +<div class="sect2">  +<h3 id="_agent"> agent</h3>  +<div class="paragraph"><p>The server can advertise the <code>agent</code> capability with a value <code>X</code> (in the  +form <code>agent=X</code>) to notify the client that the server is running version  +<code>X</code>. The client may optionally send its own agent string by including  +the <code>agent</code> capability with a value <code>Y</code> (in the form <code>agent=Y</code>) in its  +request to the server (but it MUST NOT do so if the server did not  +advertise the agent capability). The <code>X</code> and <code>Y</code> strings may contain any  +printable ASCII characters except space (i.e., the byte range 32 &lt; x &lt;  +127), and are typically of the form "package/version" (e.g.,  +"git/1.8.3.1"). The agent strings are purely informative for statistics  +and debugging purposes, and MUST NOT be used to programmatically assume  +the presence or absence of particular features.</p></div>  +</div>  +<div class="sect2">  +<h3 id="_ls_refs"> ls-refs</h3>  +<div class="paragraph"><p><code>ls-refs</code> is the command used to request a reference advertisement in v2.  +Unlike the current reference advertisement, ls-refs takes in arguments  +which can be used to limit the refs sent from the server.</p></div>  +<div class="paragraph"><p>Additional features not supported in the base command will be advertised  +as the value of the command in the capability advertisement in the form  +of a space separated list of features: "&lt;command&gt;=&lt;feature 1&gt; &lt;feature 2&gt;"</p></div>  +<div class="paragraph"><p>ls-refs takes in the following arguments:</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>symrefs  + In addition to the object pointed by it, show the underlying ref  + pointed by it when showing a symbolic ref.  +peel  + Show peeled tags.  +ref-prefix &lt;prefix&gt;  + When specified, only references having a prefix matching one of  + the provided prefixes are displayed.</code></pre>  +</div></div>  +<div class="paragraph"><p>The output of ls-refs is as follows:</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>output = *ref  + flush-pkt  +ref = PKT-LINE(obj-id SP refname *(SP ref-attribute) LF)  +ref-attribute = (symref | peeled)  +symref = "symref-target:" symref-target  +peeled = "peeled:" obj-id</code></pre>  +</div></div>  +</div>  +<div class="sect2">  +<h3 id="_fetch"> fetch</h3>  +<div class="paragraph"><p><code>fetch</code> is the command used to fetch a packfile in v2. It can be looked  +at as a modified version of the v1 fetch where the ref-advertisement is  +stripped out (since the <code>ls-refs</code> command fills that role) and the  +message format is tweaked to eliminate redundancies and permit easy  +addition of future extensions.</p></div>  +<div class="paragraph"><p>Additional features not supported in the base command will be advertised  +as the value of the command in the capability advertisement in the form  +of a space separated list of features: "&lt;command&gt;=&lt;feature 1&gt; &lt;feature 2&gt;"</p></div>  +<div class="paragraph"><p>A <code>fetch</code> request can take the following arguments:</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>want &lt;oid&gt;  + Indicates to the server an object which the client wants to  + retrieve. Wants can be anything and are not limited to  + advertised objects.</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>have &lt;oid&gt;  + Indicates to the server an object which the client has locally.  + This allows the server to make a packfile which only contains  + the objects that the client needs. Multiple 'have' lines can be  + supplied.</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>done  + Indicates to the server that negotiation should terminate (or  + not even begin if performing a clone) and that the server should  + use the information supplied in the request to construct the  + packfile.</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>thin-pack  + Request that a thin pack be sent, which is a pack with deltas  + which reference base objects not contained within the pack (but  + are known to exist at the receiving end). This can reduce the  + network traffic significantly, but it requires the receiving end  + to know how to "thicken" these packs by adding the missing bases  + to the pack.</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>no-progress  + Request that progress information that would normally be sent on  + side-band channel 2, during the packfile transfer, should not be  + sent. However, the side-band channel 3 is still used for error  + responses.</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>include-tag  + Request that annotated tags should be sent if the objects they  + point to are being sent.</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>ofs-delta  + Indicate that the client understands PACKv2 with delta referring  + to its base by position in pack rather than by an oid. That is,  + they can read OBJ_OFS_DELTA (ake type 6) in a packfile.</code></pre>  +</div></div>  +<div class="paragraph"><p>If the <em>shallow</em> feature is advertised the following arguments can be  +included in the clients request as well as the potential addition of the  +<em>shallow-info</em> section in the server&#8217;s response as explained below.</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>shallow &lt;oid&gt;  + A client must notify the server of all commits for which it only  + has shallow copies (meaning that it doesn't have the parents of  + a commit) by supplying a 'shallow &lt;oid&gt;' line for each such  + object so that the server is aware of the limitations of the  + client's history. This is so that the server is aware that the  + client may not have all objects reachable from such commits.</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>deepen &lt;depth&gt;  + Requests that the fetch/clone should be shallow having a commit  + depth of &lt;depth&gt; relative to the remote side.</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>deepen-relative  + Requests that the semantics of the "deepen" command be changed  + to indicate that the depth requested is relative to the client's  + current shallow boundary, instead of relative to the requested  + commits.</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>deepen-since &lt;timestamp&gt;  + Requests that the shallow clone/fetch should be cut at a  + specific time, instead of depth. Internally it's equivalent to  + doing "git rev-list --max-age=&lt;timestamp&gt;". Cannot be used with  + "deepen".</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>deepen-not &lt;rev&gt;  + Requests that the shallow clone/fetch should be cut at a  + specific revision specified by '&lt;rev&gt;', instead of a depth.  + Internally it's equivalent of doing "git rev-list --not &lt;rev&gt;".  + Cannot be used with "deepen", but can be used with  + "deepen-since".</code></pre>  +</div></div>  +<div class="paragraph"><p>The response of <code>fetch</code> is broken into a number of sections separated by  +delimiter packets (0001), with each section beginning with its section  +header.</p></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>output = *section  +section = (acknowledgments | shallow-info | packfile)  + (flush-pkt | delim-pkt)</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>acknowledgments = PKT-LINE("acknowledgments" LF)  + (nak | *ack)  + (ready)  +ready = PKT-LINE("ready" LF)  +nak = PKT-LINE("NAK" LF)  +ack = PKT-LINE("ACK" SP obj-id LF)</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>shallow-info = PKT-LINE("shallow-info" LF)  + *PKT-LINE((shallow | unshallow) LF)  +shallow = "shallow" SP obj-id  +unshallow = "unshallow" SP obj-id</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>packfile = PKT-LINE("packfile" LF)  + *PKT-LINE(%x01-03 *%x00-ff)</code></pre>  +</div></div>  +<div class="literalblock">  +<div class="content">  +<pre><code>acknowledgments section  + * If the client determines that it is finished with negotiations  + by sending a "done" line, the acknowledgments sections MUST be  + omitted from the server's response.</code></pre>  +</div></div>  +<div class="ulist"><ul>  +<li>  +<p>  +Always begins with the section header "acknowledgments"  +</p>  +</li>  +<li>  +<p>  +The server will respond with "NAK" if none of the object ids sent  + as have lines were common.  +</p>  +</li>  +<li>  +<p>  +The server will respond with "ACK obj-id" for all of the  + object ids sent as have lines which are common.  +</p>  +</li>  +<li>  +<p>  +A response cannot have both "ACK" lines as well as a "NAK"  + line.  +</p>  +</li>  +<li>  +<p>  +The server will respond with a "ready" line indicating that  + the server has found an acceptable common base and is ready to  + make and send a packfile (which will be found in the packfile  + section of the same response)  +</p>  +</li>  +<li>  +<p>  +If the server has found a suitable cut point and has decided  + to send a "ready" line, then the server can decide to (as an  + optimization) omit any "ACK" lines it would have sent during  + its response. This is because the server will have already  + determined the objects it plans to send to the client and no  + further negotiation is needed.  +</p>  +<div class="literalblock">  +<div class="content">  +<pre><code>shallow-info section  + * If the client has requested a shallow fetch/clone, a shallow  + client requests a fetch or the server is shallow then the  + server's response may include a shallow-info section. The  + shallow-info section will be included if (due to one of the  + above conditions) the server needs to inform the client of any  + shallow boundaries or adjustments to the clients already  + existing shallow boundaries.</code></pre>  +</div></div>  +</li>  +<li>  +<p>  +Always begins with the section header "shallow-info"  +</p>  +</li>  +<li>  +<p>  +If a positive depth is requested, the server will compute the  + set of commits which are no deeper than the desired depth.  +</p>  +</li>  +<li>  +<p>  +The server sends a "shallow obj-id" line for each commit whose  + parents will not be sent in the following packfile.  +</p>  +</li>  +<li>  +<p>  +The server sends an "unshallow obj-id" line for each commit  + which the client has indicated is shallow, but is no longer  + shallow as a result of the fetch (due to its parents being  + sent in the following packfile).  +</p>  +</li>  +<li>  +<p>  +The server MUST NOT send any "unshallow" lines for anything  + which the client has not indicated was shallow as a part of  + its request.  +</p>  +</li>  +<li>  +<p>  +This section is only included if a packfile section is also  + included in the response.  +</p>  +<div class="literalblock">  +<div class="content">  +<pre><code>packfile section  + * This section is only included if the client has sent 'want'  + lines in its request and either requested that no more  + negotiation be done by sending 'done' or if the server has  + decided it has found a sufficient cut point to produce a  + packfile.</code></pre>  +</div></div>  +</li>  +<li>  +<p>  +Always begins with the section header "packfile"  +</p>  +</li>  +<li>  +<p>  +The transmission of the packfile begins immediately after the  + section header  +</p>  +</li>  +<li>  +<p>  +The data transfer of the packfile is always multiplexed, using  + the same semantics of the <em>side-band-64k</em> capability from  + protocol version 1. This means that each packet, during the  + packfile data stream, is made up of a leading 4-byte pkt-line  + length (typical of the pkt-line format), followed by a 1-byte  + stream code, followed by the actual data.  +</p>  +<div class="literalblock">  +<div class="content">  +<pre><code>The stream code can be one of:  + 1 - pack data  + 2 - progress messages  + 3 - fatal error message just before stream aborts</code></pre>  +</div></div>  +</li>  +</ul></div>  +</div>  +</div>  +</div>  +</div>  +<div id="footnotes"><hr /></div>  +<div id="footer">  +<div id="footer-text">  +Last updated  + 2018-05-08 16:51:20 JST  +</div>  +</div>  +</body>  +</html>  
diff --git a/technical/protocol-v2.txt b/technical/protocol-v2.txt new file mode 100644 index 0000000..136179d --- /dev/null +++ b/technical/protocol-v2.txt 
@@ -0,0 +1,395 @@ + Git Wire Protocol, Version 2 +============================== + +This document presents a specification for a version 2 of Git's wire +protocol. Protocol v2 will improve upon v1 in the following ways: + + * Instead of multiple service names, multiple commands will be + supported by a single service + * Easily extendable as capabilities are moved into their own section + of the protocol, no longer being hidden behind a NUL byte and + limited by the size of a pkt-line + * Separate out other information hidden behind NUL bytes (e.g. agent + string as a capability and symrefs can be requested using 'ls-refs') + * Reference advertisement will be omitted unless explicitly requested + * ls-refs command to explicitly request some refs + * Designed with http and stateless-rpc in mind. With clear flush + semantics the http remote helper can simply act as a proxy + +In protocol v2 communication is command oriented. When first contacting a +server a list of capabilities will advertised. Some of these capabilities +will be commands which a client can request be executed. Once a command +has completed, a client can reuse the connection and request that other +commands be executed. + + Packet-Line Framing +--------------------- + +All communication is done using packet-line framing, just as in v1. See +`Documentation/technical/pack-protocol.txt` and +`Documentation/technical/protocol-common.txt` for more information. + +In protocol v2 these special packets will have the following semantics: + + * '0000' Flush Packet (flush-pkt) - indicates the end of a message + * '0001' Delimiter Packet (delim-pkt) - separates sections of a message + + Initial Client Request +------------------------ + +In general a client can request to speak protocol v2 by sending +`version=2` through the respective side-channel for the transport being +used which inevitably sets `GIT_PROTOCOL`. More information can be +found in `pack-protocol.txt` and `http-protocol.txt`. In all cases the +response from the server is the capability advertisement. + + Git Transport +~~~~~~~~~~~~~~~ + +When using the git:// transport, you can request to use protocol v2 by +sending "version=2" as an extra parameter: + + 003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0 + + SSH and File Transport +~~~~~~~~~~~~~~~~~~~~~~~~ + +When using either the ssh:// or file:// transport, the GIT_PROTOCOL +environment variable must be set explicitly to include "version=2". + + HTTP Transport +~~~~~~~~~~~~~~~~ + +When using the http:// or https:// transport a client makes a "smart" +info/refs request as described in `http-protocol.txt` and requests that +v2 be used by supplying "version=2" in the `Git-Protocol` header. + + C: Git-Protocol: version=2 + C: + C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0 + +A v2 server would reply: + + S: 200 OK + S: <Some headers> + S: ... + S: + S: 000eversion 2\n + S: <capability-advertisement> + +Subsequent requests are then made directly to the service +`$GIT_URL/git-upload-pack`. (This works the same for git-receive-pack). + + Capability Advertisement +-------------------------- + +A server which decides to communicate (based on a request from a client) +using protocol version 2, notifies the client by sending a version string +in its initial response followed by an advertisement of its capabilities. +Each capability is a key with an optional value. Clients must ignore all +unknown keys. Semantics of unknown values are left to the definition of +each key. Some capabilities will describe commands which can be requested +to be executed by the client. + + capability-advertisement = protocol-version + capability-list + flush-pkt + + protocol-version = PKT-LINE("version 2" LF) + capability-list = *capability + capability = PKT-LINE(key[=value] LF) + + key = 1*(ALPHA | DIGIT | "-_") + value = 1*(ALPHA | DIGIT | " -_.,?\/{}[]()<>!@#$%^&*+=:;") + + Command Request +----------------- + +After receiving the capability advertisement, a client can then issue a +request to select the command it wants with any particular capabilities +or arguments. There is then an optional section where the client can +provide any command specific parameters or queries. Only a single +command can be requested at a time. + + request = empty-request | command-request + empty-request = flush-pkt + command-request = command + capability-list + [command-args] + flush-pkt + command = PKT-LINE("command=" key LF) + command-args = delim-pkt + *command-specific-arg + + command-specific-args are packet line framed arguments defined by + each individual command. + +The server will then check to ensure that the client's request is +comprised of a valid command as well as valid capabilities which were +advertised. If the request is valid the server will then execute the +command. A server MUST wait till it has received the client's entire +request before issuing a response. The format of the response is +determined by the command being executed, but in all cases a flush-pkt +indicates the end of the response. + +When a command has finished, and the client has received the entire +response from the server, a client can either request that another +command be executed or can terminate the connection. A client may +optionally send an empty request consisting of just a flush-pkt to +indicate that no more requests will be made. + + Capabilities +-------------- + +There are two different types of capabilities: normal capabilities, +which can be used to to convey information or alter the behavior of a +request, and commands, which are the core actions that a client wants to +perform (fetch, push, etc). + +Protocol version 2 is stateless by default. This means that all commands +must only last a single round and be stateless from the perspective of the +server side, unless the client has requested a capability indicating that +state should be maintained by the server. Clients MUST NOT require state +management on the server side in order to function correctly. This +permits simple round-robin load-balancing on the server side, without +needing to worry about state management. + + agent +~~~~~~~ + +The server can advertise the `agent` capability with a value `X` (in the +form `agent=X`) to notify the client that the server is running version +`X`. The client may optionally send its own agent string by including +the `agent` capability with a value `Y` (in the form `agent=Y`) in its +request to the server (but it MUST NOT do so if the server did not +advertise the agent capability). The `X` and `Y` strings may contain any +printable ASCII characters except space (i.e., the byte range 32 < x < +127), and are typically of the form "package/version" (e.g., +"git/1.8.3.1"). The agent strings are purely informative for statistics +and debugging purposes, and MUST NOT be used to programmatically assume +the presence or absence of particular features. + + ls-refs +~~~~~~~~~ + +`ls-refs` is the command used to request a reference advertisement in v2. +Unlike the current reference advertisement, ls-refs takes in arguments +which can be used to limit the refs sent from the server. + +Additional features not supported in the base command will be advertised +as the value of the command in the capability advertisement in the form +of a space separated list of features: "<command>=<feature 1> <feature 2>" + +ls-refs takes in the following arguments: + + symrefs +	In addition to the object pointed by it, show the underlying ref +	pointed by it when showing a symbolic ref. + peel +	Show peeled tags. + ref-prefix <prefix> +	When specified, only references having a prefix matching one of +	the provided prefixes are displayed. + +The output of ls-refs is as follows: + + output = *ref + flush-pkt + ref = PKT-LINE(obj-id SP refname *(SP ref-attribute) LF) + ref-attribute = (symref | peeled) + symref = "symref-target:" symref-target + peeled = "peeled:" obj-id + + fetch +~~~~~~~ + +`fetch` is the command used to fetch a packfile in v2. It can be looked +at as a modified version of the v1 fetch where the ref-advertisement is +stripped out (since the `ls-refs` command fills that role) and the +message format is tweaked to eliminate redundancies and permit easy +addition of future extensions. + +Additional features not supported in the base command will be advertised +as the value of the command in the capability advertisement in the form +of a space separated list of features: "<command>=<feature 1> <feature 2>" + +A `fetch` request can take the following arguments: + + want <oid> +	Indicates to the server an object which the client wants to +	retrieve. Wants can be anything and are not limited to +	advertised objects. + + have <oid> +	Indicates to the server an object which the client has locally. +	This allows the server to make a packfile which only contains +	the objects that the client needs. Multiple 'have' lines can be +	supplied. + + done +	Indicates to the server that negotiation should terminate (or +	not even begin if performing a clone) and that the server should +	use the information supplied in the request to construct the +	packfile. + + thin-pack +	Request that a thin pack be sent, which is a pack with deltas +	which reference base objects not contained within the pack (but +	are known to exist at the receiving end). This can reduce the +	network traffic significantly, but it requires the receiving end +	to know how to "thicken" these packs by adding the missing bases +	to the pack. + + no-progress +	Request that progress information that would normally be sent on +	side-band channel 2, during the packfile transfer, should not be +	sent. However, the side-band channel 3 is still used for error +	responses. + + include-tag +	Request that annotated tags should be sent if the objects they +	point to are being sent. + + ofs-delta +	Indicate that the client understands PACKv2 with delta referring +	to its base by position in pack rather than by an oid. That is, +	they can read OBJ_OFS_DELTA (ake type 6) in a packfile. + +If the 'shallow' feature is advertised the following arguments can be +included in the clients request as well as the potential addition of the +'shallow-info' section in the server's response as explained below. + + shallow <oid> +	A client must notify the server of all commits for which it only +	has shallow copies (meaning that it doesn't have the parents of +	a commit) by supplying a 'shallow <oid>' line for each such +	object so that the server is aware of the limitations of the +	client's history. This is so that the server is aware that the +	client may not have all objects reachable from such commits. + + deepen <depth> +	Requests that the fetch/clone should be shallow having a commit +	depth of <depth> relative to the remote side. + + deepen-relative +	Requests that the semantics of the "deepen" command be changed +	to indicate that the depth requested is relative to the client's +	current shallow boundary, instead of relative to the requested +	commits. + + deepen-since <timestamp> +	Requests that the shallow clone/fetch should be cut at a +	specific time, instead of depth. Internally it's equivalent to +	doing "git rev-list --max-age=<timestamp>". Cannot be used with +	"deepen". + + deepen-not <rev> +	Requests that the shallow clone/fetch should be cut at a +	specific revision specified by '<rev>', instead of a depth. +	Internally it's equivalent of doing "git rev-list --not <rev>". +	Cannot be used with "deepen", but can be used with +	"deepen-since". + +The response of `fetch` is broken into a number of sections separated by +delimiter packets (0001), with each section beginning with its section +header. + + output = *section + section = (acknowledgments | shallow-info | packfile) + (flush-pkt | delim-pkt) + + acknowledgments = PKT-LINE("acknowledgments" LF) + (nak | *ack) + (ready) + ready = PKT-LINE("ready" LF) + nak = PKT-LINE("NAK" LF) + ack = PKT-LINE("ACK" SP obj-id LF) + + shallow-info = PKT-LINE("shallow-info" LF) + *PKT-LINE((shallow | unshallow) LF) + shallow = "shallow" SP obj-id + unshallow = "unshallow" SP obj-id + + packfile = PKT-LINE("packfile" LF) + *PKT-LINE(%x01-03 *%x00-ff) + + acknowledgments section +	* If the client determines that it is finished with negotiations + by sending a "done" line, the acknowledgments sections MUST be + omitted from the server's response. + +	* Always begins with the section header "acknowledgments" + +	* The server will respond with "NAK" if none of the object ids sent + as have lines were common. + +	* The server will respond with "ACK obj-id" for all of the + object ids sent as have lines which are common. + +	* A response cannot have both "ACK" lines as well as a "NAK" + line. + +	* The server will respond with a "ready" line indicating that + the server has found an acceptable common base and is ready to + make and send a packfile (which will be found in the packfile + section of the same response) + +	* If the server has found a suitable cut point and has decided + to send a "ready" line, then the server can decide to (as an + optimization) omit any "ACK" lines it would have sent during + its response. This is because the server will have already + determined the objects it plans to send to the client and no + further negotiation is needed. + + shallow-info section +	* If the client has requested a shallow fetch/clone, a shallow + client requests a fetch or the server is shallow then the + server's response may include a shallow-info section. The + shallow-info section will be included if (due to one of the + above conditions) the server needs to inform the client of any + shallow boundaries or adjustments to the clients already + existing shallow boundaries. + +	* Always begins with the section header "shallow-info" + +	* If a positive depth is requested, the server will compute the + set of commits which are no deeper than the desired depth. + +	* The server sends a "shallow obj-id" line for each commit whose + parents will not be sent in the following packfile. + +	* The server sends an "unshallow obj-id" line for each commit + which the client has indicated is shallow, but is no longer + shallow as a result of the fetch (due to its parents being + sent in the following packfile). + +	* The server MUST NOT send any "unshallow" lines for anything + which the client has not indicated was shallow as a part of + its request. + +	* This section is only included if a packfile section is also + included in the response. + + packfile section +	* This section is only included if the client has sent 'want' + lines in its request and either requested that no more + negotiation be done by sending 'done' or if the server has + decided it has found a sufficient cut point to produce a + packfile. + +	* Always begins with the section header "packfile" + +	* The transmission of the packfile begins immediately after the + section header + +	* The data transfer of the packfile is always multiplexed, using + the same semantics of the 'side-band-64k' capability from + protocol version 1. This means that each packet, during the + packfile data stream, is made up of a leading 4-byte pkt-line + length (typical of the pkt-line format), followed by a 1-byte + stream code, followed by the actual data. + + The stream code can be one of: +	1 - pack data +	2 - progress messages +	3 - fatal error message just before stream aborts